package mock;

import bean.OrderDetail;
import com.github.javafaker.Faker;

import java.sql.*;
import java.util.*;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import bean.OrderDetail;

public class OrderDetailDataGenerator {
    private static final String DB_URL = "jdbc:mysql://192.168.10.102:3306/driver?useSSL=false&requireSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "000000";
    private static final int BATCH_SIZE = 100;

    // 缓存 order_id, driver_id 避免重复查询
    private static List<String> orderIds = null;
    private static List<String> driverIds = null;

    public static void main(String[] args) {
        int count = 10; // 默认生成10条数据
        if (args.length >= 1) {
            count = Integer.parseInt(args[0]);
        }
        generateData(count);
    }

    public static void generateData(int count) {

//        Faker faker = new Faker(Locale.CHINA);
//        List<OrderDetail> details = new ArrayList<>();
//
//        // 初始化外键缓存
//        if (driverIds == null || driverIds.isEmpty()) {
//            driverIds = getAllDriverIds();
//            if (driverIds.isEmpty()) {
//                throw new IllegalStateException("driverIds 为空，请检查 driver 表是否有数据");
//            }
//        }
//
//        for (long i = 1; i <= count; i++) {
//            String driverId = getRandomDriverId(faker);
//            Timestamp pickupTime = generateRandomTimestamp(faker);
//
//            double basePrice = generateRandomBasePrice(faker);
//            double mileagePrice = generateRandomMileagePrice(faker);
//            double timePrice = generateRandomTimePrice(faker);
//            double totalPrice = basePrice + mileagePrice + timePrice;
//
//            OrderDetail detail = OrderDetail.builder()
//                    .order_id(String.valueOf(i))  // 保持与 OrderInfoDataGenerator 一致
//                    .driver_id(driverId)
//                    .pickup_time(pickupTime)
//                    .pickup_location(faker.address().cityName())
//                    .destination(faker.address().cityName())
//                    .distance(generateRandomDistance(faker))
//                    .time(generateRandomTimeInSeconds(faker))
//                    .base_price(basePrice)
//                    .mileage_price(mileagePrice)
//                    .time_price(timePrice)
//                    .total_price(totalPrice)
//                    .status(generateRandomStatus(faker))
//                    .payment_status(generateRandomPaymentStatus(faker))
//                    .payment_type(generateRandomPaymentType(faker))
//                    .passeger_mark(generateRandomMark(faker))
//                    .passenger_comment(generateRandomComment(faker))
//                    .build();
//
//            details.add(detail);
//        }
//
//        insertIntoDatabase(details);
        Faker faker = new Faker(Locale.CHINA);
        List<OrderDetail> details = new ArrayList<>();

        // 获取最近生成的 order_id
        List<String> orderIds = getOrderIds(count);
        if (orderIds.isEmpty()) {
            throw new IllegalStateException("没有找到可用的 order_id，请先运行 OrderInfoDataGenerator");
        }

        if (driverIds == null || driverIds.isEmpty()) {
            driverIds = getAllDriverIds();
            if (driverIds.isEmpty()) {
                throw new IllegalStateException("driverIds 为空，请检查 driver 表是否有数据");
            }
        }

        for (int i = 0; i < count && i < orderIds.size(); i++) {
            String orderId = orderIds.get(i);
            String driverId = getRandomDriverId(faker);
            Timestamp pickupTime = generateRandomTimestamp(faker);

            double basePrice = generateRandomBasePrice(faker);
            double mileagePrice = generateRandomMileagePrice(faker);
            double timePrice = generateRandomTimePrice(faker);
            double totalPrice = basePrice + mileagePrice + timePrice;

            OrderDetail detail = OrderDetail.builder()
                    .order_id(orderId)
                    .driver_id(driverId)
                    .pickup_time(pickupTime)
                    .pickup_location(faker.address().cityName())
                    .destination(faker.address().cityName())
                    .distance(generateRandomDistance(faker))
                    .time(generateRandomTimeInSeconds(faker))
                    .base_price(basePrice)
                    .mileage_price(mileagePrice)
                    .time_price(timePrice)
                    .total_price(totalPrice)
                    .status(generateRandomStatus(faker))
                    .payment_status(generateRandomPaymentStatus(faker))
                    .payment_type(generateRandomPaymentType(faker))
                    .passeger_mark(generateRandomMark(faker))
                    .passenger_comment(generateRandomComment(faker))
                    .build();

            details.add(detail);
        }

        insertIntoDatabase(details);

    }


    private static void insertIntoDatabase(List<OrderDetail> details) {
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            conn.setAutoCommit(false);
            String sql = "INSERT INTO order_detail (" +
                    "order_id, driver_id, pickup_time, pickup_location, destination, distance, time, base_price, mileage_price, time_price, total_price, status, payment_status, payment_type, passeger_mark, passenger_comment" +
                    ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                for (int i = 0; i < details.size(); i++) {
                    OrderDetail d = details.get(i);
                    pstmt.setString(1, d.getOrder_id());
                    pstmt.setString(2, d.getDriver_id());
                    pstmt.setTimestamp(3, new Timestamp(d.getPickup_time().getTime()));

                    pstmt.setString(4, d.getPickup_location());
                    pstmt.setString(5, d.getDestination());
                    pstmt.setDouble(6, d.getDistance());
                    pstmt.setInt(7, d.getTime());
                    pstmt.setDouble(8, d.getBase_price());
                    pstmt.setDouble(9, d.getMileage_price());
                    pstmt.setDouble(10, d.getTime_price());
                    pstmt.setDouble(11, d.getTotal_price());
                    pstmt.setInt(12, d.getStatus());
                    pstmt.setInt(13, d.getPayment_status());
                    pstmt.setInt(14, d.getPayment_type());
                    pstmt.setString(15, d.getPasseger_mark());
                    pstmt.setString(16, d.getPassenger_comment());
                    pstmt.addBatch();

                    if ((i + 1) % BATCH_SIZE == 0 || i == details.size() - 1) {
                        pstmt.executeBatch();
                    }
                }
                conn.commit();
                System.out.println("成功插入" + details.size() + "条订单明细信息");
            } catch (SQLException e) {
                conn.rollback();
                e.printStackTrace();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static String getRandomOrderId(Faker faker) {
        return orderIds.get(faker.random().nextInt(orderIds.size()));
    }

    private static String getRandomDriverId(Faker faker) {
        return driverIds.get(faker.random().nextInt(driverIds.size()));
    }

    private static Timestamp generateRandomTimestamp(Faker faker) {
        return new Timestamp(faker.date().past(365, TimeUnit.DAYS).getTime());
    }

    private static double generateRandomDistance(Faker faker) {
        return Math.round(faker.number().randomDouble(2, 1, 30) * 10.0) / 10.0;
    }

    private static int generateRandomTimeInSeconds(Faker faker) {
        return faker.number().numberBetween(300, 7200); // 5分钟~2小时
    }

    private static double generateRandomBasePrice(Faker faker) {
        return Math.round(faker.number().randomDouble(2, 5, 15) * 100.0) / 100.0;
    }

    private static double generateRandomMileagePrice(Faker faker) {
        return Math.round(faker.number().randomDouble(2, 5, 50) * 100.0) / 100.0;
    }

    private static double generateRandomTimePrice(Faker faker) {
        return Math.round(faker.number().randomDouble(2, 0, 20) * 100.0) / 100.0;
    }

    private static int generateRandomStatus(Faker faker) {
        return faker.random().nextInt(0, 3); // 状态：0（未完成）~3（超时）
    }

    private static int generateRandomPaymentStatus(Faker faker) {
        return faker.random().nextInt(0, 2); // 0-未支付，1-已支付，2-已退款
    }

    private static int generateRandomPaymentType(Faker faker) {
        return faker.random().nextInt(1, 3); // 1-微信，2-支付宝，3-银行卡
    }

    private static String generateRandomMark(Faker faker) {
        return String.valueOf(faker.random().nextInt(1, 5));
    }

    private static String generateRandomComment(Faker faker) {
        String[] comments = {
                "服务很好", "司机很专业", "车辆干净", "准时到达", "价格合理",
                "体验一般", "迟到几分钟", "车况不好", "没有沟通好", "下次还会选"
        };
        return comments[faker.random().nextInt(comments.length)];
    }

    /**
     * 查询所有 order_id
     */
    public static List<String> getAllOrderIds() {
        List<String> ids = new ArrayList<>();
        String query = "SELECT order_id FROM order_info";

        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(query)) {

            while (rs.next()) {
                ids.add(rs.getString("order_id"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return ids;
    }

    /**
     * 查询所有 driver_id
     */
    public static List<String> getAllDriverIds() {
        List<String> ids = new ArrayList<>();
        String query = "SELECT driver_id FROM driver";

        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(query)) {

            while (rs.next()) {
                ids.add(rs.getString("driver_id"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return ids;
    }
    public static int getCurrentMaxOrderId() {
        String query = "SELECT MAX(CAST(order_id AS UNSIGNED)) FROM order_info";
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(query)) {

            if (rs.next()) {
                return rs.getInt(1);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }
    public static List<String> getOrderIds(int limit) {
        List<String> ids = new ArrayList<>();
        String query = "SELECT order_id FROM order_info ORDER BY order_id DESC LIMIT " + limit;

        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(query)) {

            while (rs.next()) {
                ids.add(rs.getString("order_id"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        Collections.reverse(ids); // 确保顺序一致
        return ids;
    }


}
